/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mopso;

import algorithms.CSS_MOPSO;
import algorithms.MOPSO;
import algorithms.MOPSO_CDLS;
import algorithms.MOPSO_CDR;
import algorithms.M_DNPSO;
import gui.MOPSO_CDRJFrame;
import gui.MOPSO_CDLSJFrame;
import gui.CSS_MOPSOJFrame;
import gui.MOPSO_CDLSJFrame;
import gui.MOPSO_CDRJFrame;
import gui.M_DNPSOJFrame;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jfree.chart.ChartUtilities;
import problems.ZDT1;
import problems.ZDT2;
import problems.ZDT3;
import problems.ZDT4;
import problems.ZDT6;
import util.Diversity;

/**
 *
 * @author robson
 */
public class SimulationHandler {

    private Vector<Problem> problems;
    private MOPSO mopso;
    private M_DNPSO m_dnpso;
    private MOPSO_CDR mopso_CDR;
    private MOPSO_CDLS mopso_CDLS;
    private CSS_MOPSO css_mopso;
    private MOPSO_CDRJFrame frameMopso_CDR;
   
    private PerformanceMetrics pm;
    private double coverage_MOPSO_CDR__MOPSO_CDLS;
    private double coverage_MOPSO_CDLS__MOPSO_CDR;
    private double coverage_MOPSO_CDR__MOPSO;
    private double coverage_MOPSO__MOPSO_CDR;
    private double coverage_MOPSO_CDR__M_DNPSO;
    private double coverage_M_DNPSO__MOPSO_CDR;
    private double coverage_MOPSO_CDR__CSS_MOPSO;
    private double coverage_CSS_MOPSO__MOPSO_CDR;
    private Vector<MetricsReport> report_mopso_cdls;
    private Vector<MetricsReport> report_mopso_cdr;
    private Vector<MetricsReport> report_mopso;
    private Vector<MetricsReport> report_m_dnpso;
    private Vector<MetricsReport> report_css_mopso;
    private Vector<Double> report_coverage_MOPSO_CDR__MOPSO_CDLS;
    private Vector<Double> report_coverage_MOPSO_CDLS__MOPSO_CDR;
    private Vector<Double> report_coverage_MOPSO_CDR__MOPSO;
    private Vector<Double> report_coverage_MOPSO__MOPSO_CDR;
    private Vector<Double> report_coverage_MOPSO_CDR__M_DNPSO;
    private Vector<Double> report_coverage_M_DNPSO__MOPSO_CDR;
    private Vector<Double> report_coverage_MOPSO_CDR__CSS_MOPSO;
    private Vector<Double> report_coverage_CSS_MOPSO__MOPSO_CDR;
    private Vector<Double> hypervolume;
    private Vector<Double> spacing;
    private Vector<Double> maximumSpread;
    private Vector<Double> timeDuration;
    private double tempMaxValue;
    private double tempMinValue;
    private boolean debug;
    private int replicates;
    
    private Diversity diversityOperator;

    public SimulationHandler() {
        problems = new Vector<Problem>();
        pm = new PerformanceMetrics();

        problems.add(new ZDT1());
        problems.add(new ZDT2());
        problems.add(new ZDT3());
        problems.add(new ZDT4());
        problems.add(new ZDT6());

        report_mopso_cdls = new Vector<MetricsReport>();
        report_mopso_cdr = new Vector<MetricsReport>();
        report_mopso = new Vector<MetricsReport>();
        report_m_dnpso = new Vector<MetricsReport>();
        report_css_mopso = new Vector<MetricsReport>();
        report_coverage_MOPSO_CDR__MOPSO_CDLS = new Vector<Double>();
        report_coverage_MOPSO_CDLS__MOPSO_CDR = new Vector<Double>();
        report_coverage_MOPSO_CDR__MOPSO = new Vector<Double>();
        report_coverage_MOPSO__MOPSO_CDR = new Vector<Double>();
        report_coverage_MOPSO_CDR__M_DNPSO = new Vector<Double>();
        report_coverage_M_DNPSO__MOPSO_CDR = new Vector<Double>();
        report_coverage_MOPSO_CDR__CSS_MOPSO = new Vector<Double>();
        report_coverage_CSS_MOPSO__MOPSO_CDR = new Vector<Double>();
        hypervolume = new Vector<Double>();
        spacing = new Vector<Double>();
        maximumSpread = new Vector<Double>();
        timeDuration = new Vector<Double>();
        diversityOperator = new Diversity();

        debug = true;
        replicates = 30;
    }

    public void run() {

        for (int i = 0; i < problems.size(); i++) {

            System.out.println("\n\n%%problema=" + problems.get(i).getName() + " tentativas:");
            for (int r = 0; r < replicates; r++) {
                System.out.print((r + 1) + ", ");
                
                double[] maxValuesObjectives = new double[problems.get(i).getNObjectives()];
                double[] minValuesObjectives = new double[problems.get(i).getNObjectives()];

                mopso_CDR = new MOPSO_CDR(problems.get(i));
                m_dnpso = new M_DNPSO(problems.get(i));
                mopso = new MOPSO(problems.get(i));
                mopso_CDLS = new MOPSO_CDLS(problems.get(i));
                css_mopso = new CSS_MOPSO(problems.get(i));

                while (true) {
                    frameMopso_CDR = new MOPSO_CDRJFrame(mopso_CDR);
                    frameMopso_CDR.setTitle("MOPSO_CDR (" + problems.get(i).getName() + ")");
                    frameMopso_CDR.setVisible(debug);
                    mopso_CDR.run();

                    if (report_ok(mopso_CDR.getMetrics())) {
                        report_mopso_cdr.add(mopso_CDR.getMetrics());
                        break;
                    } else {
                        System.out.print("bug_mopso_cdr, ");
                    }
                }

                while (true) {
                    m_dnpso.run();

                    if (report_ok(m_dnpso.getMetrics())) {
                        report_m_dnpso.add(m_dnpso.getMetrics());
                        break;
                    } else {
                        System.out.print("bug_mopso_cdls, ");
                    }
                }

                while (true) {
                    mopso.run();

                    if (report_ok(mopso.getMetrics())) {
                        report_mopso.add(mopso.getMetrics());
                        break;
                    } else {
                        System.out.print("bug_mopso_cdls, ");
                    }
                }

                while (true) {
                    mopso_CDLS.run();

                    if (report_ok(mopso_CDLS.getMetrics())) {
                        report_mopso_cdls.add(mopso_CDLS.getMetrics());
                        break;
                    } else {
                        System.out.print("bug_mopso_cdls, ");
                    }
                }

                while (true) {
                    css_mopso.run();

                    if (report_ok(css_mopso.getMetrics())) {
                        report_css_mopso.add(css_mopso.getMetrics());
                        break;
                    } else {
                        System.out.print("bug_mopso_cdls, ");
                    }
                }
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    maxValuesObjectives[j] = Double.MIN_VALUE;
                }                
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    tempMaxValue = diversityOperator.getDimensionMaxValue(mopso_CDR.getExternalArchive(), j);
                    
                    if ( tempMaxValue > maxValuesObjectives[j] ) {
                        maxValuesObjectives[j] = tempMaxValue;
                    }                    
                }
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    tempMaxValue = diversityOperator.getDimensionMaxValue(mopso_CDLS.getExternalArchive(), j);
                    
                    if ( tempMaxValue > maxValuesObjectives[j] ) {
                        maxValuesObjectives[j] = tempMaxValue;
                    }                    
                }
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    tempMaxValue = diversityOperator.getDimensionMaxValue(mopso.getExternalArchive(), j);
                    
                    if ( tempMaxValue > maxValuesObjectives[j] ) {
                        maxValuesObjectives[j] = tempMaxValue;
                    }                    
                }
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    tempMaxValue = diversityOperator.getDimensionMaxValue_CSS(css_mopso.getExternalArchive(), j);
                    
                    if ( tempMaxValue > maxValuesObjectives[j] ) {
                        maxValuesObjectives[j] = tempMaxValue;
                    }                    
                }  
                
                for ( int j = 0; j < problems.get(i).getNObjectives(); j++ ) {
                    tempMaxValue = diversityOperator.getDimensionMaxValue(m_dnpso.getExternalArchive(), j);
                    
                    if ( tempMaxValue > maxValuesObjectives[j] ) {
                        maxValuesObjectives[j] = tempMaxValue;
                    }                    
                }   

                try {
                    ChartUtilities.saveChartAsPNG(new File("mopso-cdr-" + problems.get(i).getName() + "-" + (r + 1) + "-final_simulation.png"), mopso_CDR.getChartPanelExternalArchive().getChart(), 500, 500);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }

                try {
                    ChartUtilities.saveChartAsPNG(new File("m-dnpso-" + problems.get(i).getName() + "-" + (r + 1) + "-final_simulation.png"), m_dnpso.getChartPanelExternalArchive().getChart(), 500, 500);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }

                try {
                    ChartUtilities.saveChartAsPNG(new File("mopso-" + problems.get(i).getName() + "-" + (r + 1) + "-final_simulation.png"), mopso.getChartPanelExternalArchive().getChart(), 500, 500);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }

                try {
                    ChartUtilities.saveChartAsPNG(new File("css_mopso-" + problems.get(i).getName() + "-" + (r + 1) + "-final_simulation.png"), css_mopso.getChartPanelExternalArchive().getChart(), 500, 500);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }

                try {
                    ChartUtilities.saveChartAsPNG(new File("mopso-cdls-" + problems.get(i).getName() + "-" + (r + 1) + "-final_simulation.png"), mopso_CDLS.getChartPanelExternalArchive().getChart(), 500, 500);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }

                coverage_MOPSO_CDR__MOPSO_CDLS = pm.calculateCoverage(mopso_CDR.getExternalArchive(), mopso_CDLS.getExternalArchive(), problems.get(i));
                coverage_MOPSO_CDLS__MOPSO_CDR = pm.calculateCoverage(mopso_CDLS.getExternalArchive(), mopso_CDR.getExternalArchive(), problems.get(i));

                coverage_MOPSO_CDR__CSS_MOPSO = pm.calculateCoverage_CSS2(mopso_CDR.getExternalArchive(), css_mopso.getExternalArchive(), problems.get(i));
                coverage_CSS_MOPSO__MOPSO_CDR = pm.calculateCoverage_CSS1(css_mopso.getExternalArchive(), mopso_CDR.getExternalArchive(), problems.get(i));


                coverage_MOPSO_CDR__MOPSO = pm.calculateCoverage(mopso_CDR.getExternalArchive(), mopso.getExternalArchive(), problems.get(i));
                coverage_MOPSO__MOPSO_CDR = pm.calculateCoverage(mopso.getExternalArchive(), mopso_CDR.getExternalArchive(), problems.get(i));

                coverage_MOPSO_CDR__M_DNPSO = pm.calculateCoverage(mopso_CDR.getExternalArchive(), m_dnpso.getExternalArchive(), problems.get(i));
                coverage_M_DNPSO__MOPSO_CDR = pm.calculateCoverage(m_dnpso.getExternalArchive(), mopso_CDR.getExternalArchive(), problems.get(i));

                report_coverage_MOPSO_CDR__MOPSO_CDLS.add(coverage_MOPSO_CDR__MOPSO_CDLS);
                report_coverage_MOPSO_CDLS__MOPSO_CDR.add(coverage_MOPSO_CDLS__MOPSO_CDR);

                report_coverage_MOPSO_CDR__CSS_MOPSO.add(coverage_MOPSO_CDR__CSS_MOPSO);
                report_coverage_CSS_MOPSO__MOPSO_CDR.add(coverage_CSS_MOPSO__MOPSO_CDR);

                report_coverage_MOPSO_CDR__MOPSO.add(coverage_MOPSO_CDR__MOPSO);
                report_coverage_MOPSO__MOPSO_CDR.add(coverage_MOPSO__MOPSO_CDR);

                report_coverage_MOPSO_CDR__M_DNPSO.add(coverage_MOPSO_CDR__M_DNPSO);
                report_coverage_M_DNPSO__MOPSO_CDR.add(coverage_M_DNPSO__MOPSO_CDR);
            }

            System.out.print("\n\n\n");

            System.out.println("\\begin{table}[!h]");
            System.out.println("\\begin{center}");
            System.out.println("\\caption{Mean value and standard deviation for 30 trials for problem " + problems.get(i).getName() + "}");
            System.out.println("\\begin{tabular}{|c|c|c|c|c|}");
            System.out.println("\\hline");
            System.out.println("Algorithm   & Coverage (CDR,*) & Coverage (*,CDR) & Hypervolume  &  Spacing & Maximum Spread  &  Time (sec.)  \\\\");
            System.out.println("            &                  &                  &              &          &                 &              \\\\");
            System.out.println("\\hline");
            System.out.println("\\hline");


            for (MetricsReport r : report_mopso) {
                hypervolume.add(r.getHypervolume());
                spacing.add(r.getSpacing());
                maximumSpread.add(r.getMaximumSpread());
                timeDuration.add(r.getTimeDuration());
            }

            System.out.println("%% hypervolume=" + hypervolume);
            System.out.println("%% spacing=" + spacing);
            System.out.println("%% maximumSpread=" + maximumSpread);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO_CDR__MOPSO);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO__MOPSO_CDR);

            System.out.printf("MOPSO       &    %.10f     &    %.10f     &    %.10f     &    %.10f      &    %.10f   &    %.3f      \\\\\n", StatisticsOperators.media(report_coverage_MOPSO_CDR__MOPSO), StatisticsOperators.media(report_coverage_MOPSO__MOPSO_CDR), StatisticsOperators.media(hypervolume), StatisticsOperators.media(spacing), StatisticsOperators.media(maximumSpread), StatisticsOperators.media(timeDuration));
            System.out.printf("            &   (%.10f)    &   (%.10f)    &   (%.10f)    &   (%.10f)     &   (%.10f)  &   (%.3f)     \\\\\n", StatisticsOperators.desvio_padrao(report_coverage_MOPSO_CDR__MOPSO), StatisticsOperators.desvio_padrao(report_coverage_MOPSO__MOPSO_CDR), StatisticsOperators.desvio_padrao(hypervolume), StatisticsOperators.desvio_padrao(spacing), StatisticsOperators.desvio_padrao(maximumSpread), StatisticsOperators.desvio_padrao(timeDuration));
            System.out.println("\\hline");

            hypervolume.clear();
            spacing.clear();
            maximumSpread.clear();
            timeDuration.clear();

            for (MetricsReport r : report_m_dnpso) {
                hypervolume.add(r.getHypervolume());
                spacing.add(r.getSpacing());
                maximumSpread.add(r.getMaximumSpread());
                timeDuration.add(r.getTimeDuration());
            }

            System.out.println("%% hypervolume=" + hypervolume);
            System.out.println("%% spacing=" + spacing);
            System.out.println("%% maximumSpread=" + maximumSpread);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO_CDR__M_DNPSO);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_M_DNPSO__MOPSO_CDR);

            System.out.printf("m-DNPSO     &    %.10f     &    %.10f     &    %.10f     &    %.10f      &    %.10f   &    %.3f      \\\\\n", StatisticsOperators.media(report_coverage_MOPSO_CDR__M_DNPSO), StatisticsOperators.media(report_coverage_M_DNPSO__MOPSO_CDR), StatisticsOperators.media(hypervolume), StatisticsOperators.media(spacing), StatisticsOperators.media(maximumSpread), StatisticsOperators.media(timeDuration));
            System.out.printf("            &   (%.10f)    &   (%.10f)    &   (%.10f)    &   (%.10f)     &   (%.10f)  &   (%.3f)     \\\\\n", StatisticsOperators.desvio_padrao(report_coverage_MOPSO_CDR__M_DNPSO), StatisticsOperators.desvio_padrao(report_coverage_M_DNPSO__MOPSO_CDR), StatisticsOperators.desvio_padrao(hypervolume), StatisticsOperators.desvio_padrao(spacing), StatisticsOperators.desvio_padrao(maximumSpread), StatisticsOperators.desvio_padrao(timeDuration));
            System.out.println("\\hline");

            hypervolume.clear();
            spacing.clear();
            maximumSpread.clear();
            timeDuration.clear();

            for (MetricsReport r : report_mopso_cdls) {
                hypervolume.add(r.getHypervolume());
                spacing.add(r.getSpacing());
                maximumSpread.add(r.getMaximumSpread());
                timeDuration.add(r.getTimeDuration());
            }

            System.out.println("%% hypervolume=" + hypervolume);
            System.out.println("%% spacing=" + spacing);
            System.out.println("%% maximumSpread=" + maximumSpread);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO_CDR__MOPSO_CDLS);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO_CDLS__MOPSO_CDR);

            System.out.printf("MOPSO       &    %.10f     &    %.10f     &    %.10f     &    %.10f      &    %.10f   &    %.3f      \\\\\n", StatisticsOperators.media(report_coverage_MOPSO_CDR__MOPSO_CDLS), StatisticsOperators.media(report_coverage_MOPSO_CDLS__MOPSO_CDR), StatisticsOperators.media(hypervolume), StatisticsOperators.media(spacing), StatisticsOperators.media(maximumSpread), StatisticsOperators.media(timeDuration));
            System.out.printf("CDLS        &   (%.10f)    &   (%.10f)    &   (%.10f)    &   (%.10f)     &   (%.10f)  &   (%.3f)     \\\\\n", StatisticsOperators.desvio_padrao(report_coverage_MOPSO_CDR__MOPSO_CDLS), StatisticsOperators.desvio_padrao(report_coverage_MOPSO_CDLS__MOPSO_CDR), StatisticsOperators.desvio_padrao(hypervolume), StatisticsOperators.desvio_padrao(spacing), StatisticsOperators.desvio_padrao(maximumSpread), StatisticsOperators.desvio_padrao(timeDuration));
            System.out.println("\\hline");

            hypervolume.clear();
            spacing.clear();
            maximumSpread.clear();
            timeDuration.clear();

            for (MetricsReport r : report_css_mopso) {
                hypervolume.add(r.getHypervolume());
                spacing.add(r.getSpacing());
                maximumSpread.add(r.getMaximumSpread());
                timeDuration.add(r.getTimeDuration());
            }

            System.out.println("%% hypervolume=" + hypervolume);
            System.out.println("%% spacing=" + spacing);
            System.out.println("%% maximumSpread=" + maximumSpread);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_MOPSO_CDR__CSS_MOPSO);
            System.out.println("%% coverage_CDR_CDLS=" + report_coverage_CSS_MOPSO__MOPSO_CDR);

            System.out.printf("CSS         &    %.10f     &    %.10f     &    %.10f     &    %.10f      &    %.10f   &    %.3f      \\\\\n", StatisticsOperators.media(report_coverage_MOPSO_CDR__CSS_MOPSO), StatisticsOperators.media(report_coverage_CSS_MOPSO__MOPSO_CDR), StatisticsOperators.media(hypervolume), StatisticsOperators.media(spacing), StatisticsOperators.media(maximumSpread), StatisticsOperators.media(timeDuration));
            System.out.printf("MOPSO       &   (%.10f)    &   (%.10f)    &   (%.10f)    &   (%.10f)     &   (%.10f)  &   (%.3f)     \\\\\n", StatisticsOperators.desvio_padrao(report_coverage_MOPSO_CDR__CSS_MOPSO), StatisticsOperators.desvio_padrao(report_coverage_CSS_MOPSO__MOPSO_CDR), StatisticsOperators.desvio_padrao(hypervolume), StatisticsOperators.desvio_padrao(spacing), StatisticsOperators.desvio_padrao(maximumSpread), StatisticsOperators.desvio_padrao(timeDuration));
            System.out.println("\\hline");

            hypervolume.clear();
            spacing.clear();
            maximumSpread.clear();
            timeDuration.clear();

            for (MetricsReport r : report_mopso_cdr) {
                hypervolume.add(r.getHypervolume());
                spacing.add(r.getSpacing());
                maximumSpread.add(r.getMaximumSpread());
                timeDuration.add(r.getTimeDuration());
            }

            System.out.println("%% hypervolume=" + hypervolume);
            System.out.println("%% spacing=" + spacing);
            System.out.println("%% maximumSpread=" + maximumSpread);            

            System.out.printf("MOPSO       &    --     &    --     &    %.10f     &    %.10f      &    %.10f   &    %.3f      \\\\\n", StatisticsOperators.media(hypervolume), StatisticsOperators.media(spacing), StatisticsOperators.media(maximumSpread), StatisticsOperators.media(timeDuration));
            System.out.printf("CDR         &    --     &    --     &   (%.10f)    &   (%.10f)     &   (%.10f)  &   (%.3f)     \\\\\n", StatisticsOperators.desvio_padrao(hypervolume), StatisticsOperators.desvio_padrao(spacing), StatisticsOperators.desvio_padrao(maximumSpread), StatisticsOperators.desvio_padrao(timeDuration));
            System.out.println("\\hline");


            hypervolume.clear();
            spacing.clear();
            maximumSpread.clear();
            timeDuration.clear();

            System.out.println("\\end{tabular}");
            System.out.println("\\label{tabela_problema_" + problems.get(i).getName() + "}");
            System.out.println("\\end{center}");
            System.out.println("\\end{table}");
            System.out.println("\\FloatBarrier");


            report_coverage_MOPSO_CDR__MOPSO_CDLS.clear();
            report_coverage_MOPSO_CDLS__MOPSO_CDR.clear();

            report_coverage_MOPSO_CDR__CSS_MOPSO.clear();
            report_coverage_CSS_MOPSO__MOPSO_CDR.clear();

            report_coverage_MOPSO_CDR__MOPSO.clear();
            report_coverage_MOPSO__MOPSO_CDR.clear();

            report_coverage_MOPSO_CDR__M_DNPSO.clear();
            report_coverage_M_DNPSO__MOPSO_CDR.clear();

            report_css_mopso.clear();
            report_m_dnpso.clear();
            report_mopso.clear();
            report_mopso_cdls.clear();
            report_mopso_cdr.clear();
        }
    }

    /**
     * @param args the command line arguments
     */
    public static boolean report_ok(MetricsReport mr) {
        if (Double.isNaN(mr.getHypervolume()) ||
                Double.isNaN(mr.getMaximumSpread()) ||
                Double.isNaN(mr.getSpacing())) {
            return false;
        } else {
            return true;
        }
    }
}
